package game;

import entities.Gate;
import entities.Player;
import gfx.Background;
import gfx.Firework;
import gfx.GUI;
import gfx.Glyphs;
import gfx.Image;
import gfx.PressableButton;

import java.text.DecimalFormat;

import javax.microedition.khronos.opengles.GL10;

import gfx.Camera;
import util.GameClock;
import util.GameVars;
import util.Logger;
import util.VertexBuffer;
import android.graphics.PointF;

public class Stage {
	private GUI gui;
	
	private Background bg;
	
	private Image gateImage;
	
	private Gate[] gateArray;
	
	private PressableButton[] pauseButtonArray;
	
	private Firework[] fireworkArray;

	private PressableButton selectedButton;
	
	private PressableButton retryButton;
	private PressableButton quitButton;
	
	private PressableButton nextStageButton;
	private PressableButton returnToSelectionButton;
	private PressableButton victoryQuitButton;
	private PressableButton victoryRetryButton;
	
	// 00000000
	DecimalFormat nf;
	
	private String problemString;
	
	private short id;

	private short[] answerArray;
	private short[][] problemValueArray;
	private short[][] problemOperationArray;
	
	private float speed;
	
	private float[] overlay = new float[12];
	
//	private float currentAnswer;
//	private String currentQuestion;
	
	private short currentRow;
	
	private short difficulty;
	
	private short gateIterator;
	private short pauseButtonIterator;
	private short stringIterator;
	
	private short fireworkUpdateIterator;
	private short fireworkDrawIterator;
	
	private boolean isLoaded;
	private boolean hasGraphicsLoaded;
	private boolean isPaused = false;
	private boolean kill = false;
	
	private boolean backToSelection = false;

	private boolean isGameOver = false;
	private boolean isWon = false;

	private boolean reloading = false;
	
//	private boolean oddGate;
	private short triCounter;
	
	private Player player;
	
	
	public Stage(short stageID, short difficulty){
		hasGraphicsLoaded = false;
		
		load(stageID, difficulty);
	}
	
	/** Used mainly to restart the world */
	private void load(short stageID, short difficulty){
		id = stageID; 
		this.difficulty = difficulty;
		
		currentRow = 0;

//		// TODO this is where I designate how long the run is.
//		answerArray = new short[10];
		// XXX Switched to an infinite run
		answerArray = new short[3];
		
		generateProblems();
		
		setProblemToString(currentRow);
		
		isLoaded = false;
		isWon = false;
		isGameOver = false;
		
//		oddGate = true;
		triCounter = 0;
		
		// Resume and Quit
		pauseButtonArray = new PressableButton[2];
		pauseButtonArray[0] = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Resume", null, 3, 0.75f, GameVars.BUTTON_NUM_RESUME);
		pauseButtonArray[1] = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Quit", null, 3, 0.75f, GameVars.BUTTON_NUM_GOTO_MENU);

		for(pauseButtonIterator = 0; pauseButtonIterator < pauseButtonArray.length; ++pauseButtonIterator)
			pauseButtonArray[pauseButtonIterator].setCenter(2.5f + pauseButtonIterator * 0.25f, 5.5f - pauseButtonIterator - pauseButtonIterator * .25f);

		returnToSelectionButton = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Selection", null, 3, 0.75f, GameVars.BUTTON_NUM_RETURN_TO_SELECTION);
		victoryRetryButton = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Again!", null, 3, 0.75f, GameVars.BUTTON_NUM_RETRY);
		victoryQuitButton = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Quit", null, 3, 0.75f, GameVars.BUTTON_NUM_QUIT);

		victoryRetryButton.setCenter(3, 5.5f);
		returnToSelectionButton.setCenter(3f, 4.5f);
		victoryQuitButton.setCenter(3, 3.5f);
		
		retryButton = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Again!", null, 3, 0.75f, GameVars.BUTTON_NUM_RETRY);
		quitButton = new PressableButton(GameVars.BUTTON_TYPE_MENU, "Quit", null, 3, 0.75f, GameVars.BUTTON_NUM_QUIT);

		retryButton.setCenter(3, 5.5f);
		quitButton.setCenter(3, 4.5f);
		
		if(gateImage == null)
			gateImage = new Image(GameVars.TEXTURE_GATE, 1, 1);

		gateArray = new Gate[answerArray.length * 5];
		
//		for(int j = 0; j < answerArray.length; ++j){
////			answerArray[j] = (short) (Math.random() * 5);
//			Logger.log("Answers: " + answerArray[j]); 
//		}
		for(short i = 0; i < gateArray.length / 5; ++i){
			short answerLane = (short) (Math.random() * 5);
			short lowerCount = (short) (Math.random() * 4);
			if(answerArray[i] <= 4)
				lowerCount = answerArray[i] - lowerCount < 0 ? answerArray[i] : lowerCount;
			short lower = answerArray[i];
			short higher = answerArray[i];
			
			gateArray[i * 5 + answerLane] = new Gate(difficulty, answerArray[i], true, (short) (answerLane + 1), (short) (i));
			
			for(short s = 0; s < 4; ++s){
//				Logger.log("Lower Count: " + lowerCount);
				short randomGate = (short) (Math.random() * 5);
				while(gateArray[randomGate + i * 5] != null){
					++randomGate;
					if(randomGate % 5 == 0)
						randomGate -= 5;
				}
				if(lowerCount > 0){
					lower -= (short) (Math.random() * (lower / lowerCount) + 1);
//					if((s > answerLane ? (Math.random() * (5 - s)) : (Math.random() * (4 - s))) < lowerCount){
					gateArray[i * 5 + randomGate] = new Gate(difficulty, lower, false, (short) (randomGate + 1), (short) (i));
					--lowerCount;
					continue;
				}
				higher += (short) (Math.random() * (5) + 1);
				gateArray[i * 5 + randomGate] = new Gate(difficulty, higher, false, (short) (randomGate + 1), (short) (i));
			}
//				gateArray[i] = new Gate(difficulty, answerArray[i/5], i % 5 == answerArray[i / 5] ? true : false, (short) (i % 5 + 1), (short) (i / 5));
		}
		
		
		gui = new GUI();
		
		player = new Player();
		isLoaded = false;
		
		if(bg == null)
			bg = new Background();
		else
			bg.reload();
		
		overlay[0] = 0;
		overlay[1] = 0;
		overlay[2] = 0;
		overlay[3] = 0;
		overlay[4] = Camera.SCREEN_HEIGHT;
		overlay[5] = 0;
		overlay[6] = Camera.SCREEN_WIDTH;
		overlay[7] = 0;
		overlay[8] = 0;
		overlay[9] = Camera.SCREEN_WIDTH;
		overlay[10] = Camera.SCREEN_HEIGHT;
		overlay[11] = 0;
		
		fireworkArray = new Firework[answerArray.length];
		
		for(int f = 0; f < fireworkArray.length; ++f)
			fireworkArray[f] = new Firework();
		
		speed = GameVars.TRANSLATION_MOD;
		
		resume();
		
		isLoaded = true;
	}
	
	public void loadGraphics(GL10 gl){
		bg.loadGraphics((short) 0, gl);
		hasGraphicsLoaded = true; 
	}
	
	// Generates all the problems for one stage. [Row][Stuff]
	private void generateProblems(){
		problemValueArray = new short[answerArray.length][];
		problemOperationArray = new short[answerArray.length][];
		
		for(int k = 0; k < answerArray.length; ++k){
			switch(difficulty){
			case GameVars.DIFFICULTY_EASY:
				problemValueArray[k] = new short[2];
				break;
			case GameVars.DIFFICULTY_NORMAL:
				problemValueArray[k] = new short[2];
				break;
			case GameVars.DIFFICULTY_HARD:
				problemValueArray[k] = new short[2 + (short) (Math.random() * 2)];
				break;
			case GameVars.DIFFICULTY_INSANE:
				problemValueArray[k] = new short[2 + (short) (Math.random() * 3)];
				break;
			}
			
			problemOperationArray[k] = new short[problemValueArray[k].length - 1];
			
			for(int q = 0; q < problemOperationArray[k].length; ++q)
				switch(id){
				case GameVars.STAGE_OPERATORS_ADD:
					problemOperationArray[k][q] = GameVars.OPERATION_ADD;
					break;
				case GameVars.STAGE_OPERATORS_SUB:
					problemOperationArray[k][q] = GameVars.OPERATION_SUB;
					break;
				case GameVars.STAGE_OPERATORS_ADD_AND_SUB:
					if(Math.random() > .5)
						problemOperationArray[k][q] = GameVars.OPERATION_SUB;
					else
						problemOperationArray[k][q] = GameVars.OPERATION_ADD;
					break;
				case GameVars.STAGE_OPERATORS_MUL:
					problemOperationArray[k][q] = GameVars.OPERATION_MUL;
					break;
				case GameVars.STAGE_OPERATORS_DIV:
					problemOperationArray[k][q] = GameVars.OPERATION_DIV;
					break;
				case GameVars.STAGE_OPERATORS_MUL_AND_DIV:
					if(Math.random() > .5)
						problemOperationArray[k][q] = GameVars.OPERATION_MUL;
					else
						problemOperationArray[k][q] = GameVars.OPERATION_DIV;
					break;
				}
			
			for(int w = 0; w < problemValueArray[k].length; ++w){
				if(w > 0)
					if(problemOperationArray[k][w - 1] == GameVars.OPERATION_DIV){
						problemValueArray[k][w] = (short) (Math.random() * 4 + 1);
						problemValueArray[k][0] *= problemValueArray[k][w];
						continue;
					}
				problemValueArray[k][w] = (short) (Math.random() * 10);
			}
			
			for(int t = 0; t < problemValueArray[k].length; ++t)
				if(t == 0)
					answerArray[k] = problemValueArray[k][t];
				else
					switch(problemOperationArray[k][t - 1]){
					case GameVars.OPERATION_ADD:
						answerArray[k] += problemValueArray[k][t];
						break;
					case GameVars.OPERATION_SUB:
						answerArray[k] -= problemValueArray[k][t];
						while(answerArray[k] < 0){
							answerArray[k] -= problemValueArray[k][0];
							problemValueArray[k][0] += (short) (Math.random() * 10);
							answerArray[k] += problemValueArray[k][0];
						}
						break;
					case GameVars.OPERATION_MUL:
						answerArray[k] *= problemValueArray[k][t];
						break;
					case GameVars.OPERATION_DIV:
						answerArray[k] /= problemValueArray[k][t];
						break;
					}
		}
	}
	
	private void generateNewProblem(int i){		
		switch(difficulty){
		case GameVars.DIFFICULTY_EASY:
			problemValueArray[i] = new short[2];
			break;
		case GameVars.DIFFICULTY_NORMAL:
			problemValueArray[i] = new short[2];
			break;
		case GameVars.DIFFICULTY_HARD:
			problemValueArray[i] = new short[2 + (short) (Math.random() * 2)];
			break;
		case GameVars.DIFFICULTY_INSANE:
			problemValueArray[i] = new short[2 + (short) (Math.random() * 3)];
			break;
		}
		
		problemOperationArray[i] = new short[problemValueArray[i].length - 1];
		
		for(int q = 0; q < problemOperationArray[i].length; ++q)
			switch(id){
			case GameVars.STAGE_OPERATORS_ADD:
				problemOperationArray[i][q] = GameVars.OPERATION_ADD;
				break;
			case GameVars.STAGE_OPERATORS_SUB:
				problemOperationArray[i][q] = GameVars.OPERATION_SUB;
				break;
			case GameVars.STAGE_OPERATORS_ADD_AND_SUB:
				if(Math.random() > .5)
					problemOperationArray[i][q] = GameVars.OPERATION_SUB;
				else
					problemOperationArray[i][q] = GameVars.OPERATION_ADD;
				break;
			case GameVars.STAGE_OPERATORS_MUL:
				problemOperationArray[i][q] = GameVars.OPERATION_MUL;
				break;
			case GameVars.STAGE_OPERATORS_DIV:
				problemOperationArray[i][q] = GameVars.OPERATION_DIV;
				break;
			case GameVars.STAGE_OPERATORS_MUL_AND_DIV:
				if(Math.random() > .5)
					problemOperationArray[i][q] = GameVars.OPERATION_MUL;
				else
					problemOperationArray[i][q] = GameVars.OPERATION_DIV;
				break;
			}
		
		for(int w = 0; w < problemValueArray[i].length; ++w){
			if(w > 0)
				if(problemOperationArray[i][w - 1] == GameVars.OPERATION_DIV){
					problemValueArray[i][w] = (short) (Math.random() * 4 + 1);
					problemValueArray[i][0] *= problemValueArray[i][w];
					continue;
				}
			problemValueArray[i][w] = (short) (Math.random() * 10);
		}
		
		for(int t = 0; t < problemValueArray[i].length; ++t)
			if(t == 0)
				answerArray[i] = problemValueArray[i][t];
			else
				switch(problemOperationArray[i][t - 1]){
				case GameVars.OPERATION_ADD:
					answerArray[i] += problemValueArray[i][t];
					break;
				case GameVars.OPERATION_SUB:
					answerArray[i] -= problemValueArray[i][t];
					while(answerArray[i] < 0){
						answerArray[i] -= problemValueArray[i][0];
						problemValueArray[i][0] += (short) (Math.random() * 10);
						answerArray[i] += problemValueArray[i][0];
					}
					break;
				case GameVars.OPERATION_MUL:
					answerArray[i] *= problemValueArray[i][t];
					break;
				case GameVars.OPERATION_DIV:
					answerArray[i] /= problemValueArray[i][t];
					break;
				}
	}
	
	private void generateNewAnswer(int index){
			short answerLane = (short) (Math.random() * 5);
			short lowerCount = (short) (Math.random() * 4);
			if(answerArray[index] <= 4)
				lowerCount = answerArray[index] - lowerCount < 0 ? answerArray[index] : lowerCount;
			short lower = answerArray[index];
			short higher = answerArray[index];
			
//			gateArray[index * 5 + answerLane] = new Gate(difficulty, answerArray[index], true, (short) (answerLane + 1), (short) (index));
			gateArray[index * 5 + answerLane].setIsRight(true);
			gateArray[index * 5 + answerLane].setValue(answerArray[index]);
			gateArray[index * 5 + answerLane].setIsSet(true);
			
			Logger.log("Lane: " + answerLane);

			for(short s = 0; s < 4; ++s){
//				Logger.log("Lower Count: " + lowerCount);
				short randomGate = (short) (Math.random() * 5);
				while(gateArray[randomGate + index * 5].isSet()){
					++randomGate;
					if(randomGate % 5 == 0)
						randomGate -= 5;
				}
				if(lowerCount > 0){
					lower -= (short) (Math.random() * (lower / lowerCount) + 1);
//					if((s > answerLane ? (Math.random() * (5 - s)) : (Math.random() * (4 - s))) < lowerCount){
//					gateArray[index * 5 + randomGate] = new Gate(difficulty, lower, false, (short) (randomGate + 1), (short) (index));
					gateArray[index * 5 + randomGate].setIsRight(false);
					gateArray[index * 5 + randomGate].setValue(lower);
					--lowerCount;
					continue;
				}
				higher += (short) (Math.random() * (5) + 1);
//				gateArray[index * 5 + randomGate] = new Gate(difficulty, higher, false, (short) (randomGate + 1), (short) (index));
				gateArray[index * 5 + randomGate].setIsRight(false);
				gateArray[index * 5 + randomGate].setValue(higher);
				gateArray[index * 5 + randomGate].setIsSet(true);
			}
	}
	
	// Returns the String for Row r
	private void setProblemToString(short r){
		problemString = "";
		for(stringIterator = 0; stringIterator < problemValueArray[r].length; ++stringIterator){
			problemString += Short.toString(problemValueArray[r][stringIterator]);
			if(stringIterator < problemOperationArray[r].length)
				switch(problemOperationArray[r][stringIterator]){
				case GameVars.OPERATION_ADD:
					problemString += ("+");
					break;
				case GameVars.OPERATION_SUB:
					problemString += ("-");
					break;
				case GameVars.OPERATION_MUL:
					problemString += ("x");
					break;
				case GameVars.OPERATION_DIV:
					problemString += ("/");
					break;
				}
		}
		Logger.log("Problem: " + problemString);
	}
	
	private void checkCollision(){
		// XXX Commented out to test infinite run
//		if(currentRow + 1 > gateArray.length / 5)
//			return;
//		if(bg.getTranslation() + player.getY() + player.getHeight() * 0.5f + gateImage.getHeight() * 0.5f - GameVars.ROW_DISTANCE[difficulty] * (currentRow + 1) - GameVars.GATE_START_MOD > 0){
//			if(!gateArray[currentRow * 5 + player.getLane() - 1].isRight())
//				player.handleDeath();
////			pause();
//			fireworkArray[currentRow].fire();
//			++currentRow;
//			if(currentRow < answerArray.length)
//				setProblemToString(currentRow);
//		}

		if(bg.getTranslation() + player.getY() + player.getHeight() * 0.5f + gateImage.getHeight() * 0.5f - GameVars.ROW_DISTANCE[difficulty] * (currentRow + 1) - GameVars.GATE_START_MOD > 0){
			if(!gateArray[(triCounter * 5) + player.getLane() - 1].isRight())
				player.handleDeath();
//			pause();
			fireworkArray[triCounter].fire(player.getLane());
			
			if(currentRow > 0)
				for(int a = 0; a < 5; ++a){
					fireworkArray[(triCounter + 2) % 3].reset();
					
					gateArray[(triCounter + 2) % 3 * 5 + a].setIsSet(false);
					gateArray[(triCounter + 2) % 3 * 5 + a].moveBack();
				}
			generateNewProblem((triCounter + 2) % 3);
			generateNewAnswer((triCounter + 2) % 3);
			
			++currentRow;
			++triCounter;
			triCounter %= 3;
			Logger.log("Supposed Answer: " + answerArray[triCounter]);
			setProblemToString(triCounter);
			
			speed += GameVars.SPEED_INCREMENT[difficulty];
		}
	}
	
	private void checkIsWon(){
		if(bg.getTranslation() + player.getY() > gateArray.length / 5 * GameVars.ROW_DISTANCE[difficulty] + GameVars.GATE_START_MOD)
			isWon = true;
	}
	 
	public void update(long time){
		if(reloading){
			load(id, difficulty);
			reloading = false;
			return;
		}
		
		if(isPaused)
			return;
		
		for(fireworkUpdateIterator = 0; fireworkUpdateIterator < fireworkArray.length; ++fireworkUpdateIterator)
			fireworkArray[fireworkUpdateIterator].update(time);
			
		gui.update(time);
		
		checkCollision();
		
//		checkIsWon();
		
		if(player.isDead()){
			// Update Death Animation only, and blargity.
			if(!isGameOver)
				isGameOver = true;
			pause();
			return;
		}
		
		if(gui.isMoved())
			if(bg.getTranslation() + player.getY() - GameVars.ROW_DISTANCE[difficulty] * currentRow < 0)
				gui.handleMoved(); 
			else player.move(gui.handleMoved());
		player.update(time);
		
		bg.update(time, speed);
	}
	
	public void draw(GL10 gl){
		bg.draw(gl);
		
		player.draw(gl);
		
		gl.glPushMatrix();
		gl.glTranslatef(0, -bg.getTranslation(), 0);
		
//		for(gateIterator = 0; gateIterator < gateArray.length; ++gateIterator)
		// XXX Changed to Infinite Run
//		for(gateIterator = (short) ((currentRow - 1) * 5) < 0 ? 0 : (short) ((currentRow - 1) * 5); gateIterator < (currentRow + 1) * 5; ++gateIterator)
//			if(gateIterator >= gateArray.length)
//				break;
//			else
//				gateArray[gateIterator].draw(gl, gateImage, !isPaused);
		for(gateIterator = 0; gateIterator < gateArray.length; ++gateIterator)
			gateArray[gateIterator].draw(gl, gateImage, !isPaused);
		
		gl.glPopMatrix();
		
		gl.glPushMatrix();
		
		gl.glTranslatef(0, player.getY(), 0);
		
		for(fireworkDrawIterator = 0; fireworkDrawIterator < fireworkArray.length; ++fireworkDrawIterator)
			fireworkArray[fireworkDrawIterator].draw(gl);
		
		gl.glPopMatrix();

		gui.draw(gl);
		
		gl.glPushMatrix();
		
		gl.glTranslatef(3, 3.5f, 0);
		
		Glyphs.drawString(gl, "Score: " + currentRow, null, GameVars.TEXT_ALIGNMENT_CENTER);
		
		gl.glPopMatrix();

		// XXX Changed to Infinate run
//		if(currentRow < answerArray.length)
			drawQuestion(gl);
		
		
		if(isWon){
//			drawOverlay(gl, .5f);
			returnToSelectionButton.draw(gl);
			victoryRetryButton.draw(gl);
			victoryQuitButton.draw(gl);
			
			gl.glPushMatrix();
			gl.glTranslatef(3, 7.5f, 0);
			gl.glScalef(2, 2, 1);
			gl.glColor4f(1, 1, 1, 1);
			Glyphs.drawString(gl, "Congratulations!", null, GameVars.TEXT_ALIGNMENT_CENTER);
			gl.glPopMatrix();
			
			return;
		}
		
		if(isGameOver){
			drawOverlay(gl, .5f);
			retryButton.draw(gl);
			quitButton.draw(gl);
			
			gl.glPushMatrix();
			gl.glTranslatef(3, 8.5f, 0);
			gl.glScalef(2, 2, 1);
			gl.glColor4f(1, 1, 1, 1);
//			Glyphs.drawString(gl, "Aww...", null, GameVars.TEXT_ALIGNMENT_CENTER);
			gl.glTranslatef(0, -0.5f, 0);
			Glyphs.drawString(gl, "Game Over", null, GameVars.TEXT_ALIGNMENT_CENTER);
			gl.glPopMatrix();
			
			return;
		}
		
		// Move to a drawPaused()?
		if(isPaused){
			drawOverlay(gl, .75f);
			// No Pause Button Array right now :<
			for(pauseButtonIterator = 0; pauseButtonIterator < pauseButtonArray.length; ++pauseButtonIterator)
				pauseButtonArray[pauseButtonIterator].draw(gl);
			
			gl.glPushMatrix();
			gl.glTranslatef(3, 7.5f, 0);
			gl.glScalef(2, 2, 1);
			gl.glColor4f(1, 1, 1, 1);
			Glyphs.drawString(gl, "Paused!", null, GameVars.TEXT_ALIGNMENT_CENTER);
			gl.glPopMatrix();
		}
	}
	
	private void drawQuestion(GL10 gl){
		// Temp.  Change to a more Dynamic Thingy
		if(isPaused)
			Glyphs.drawString(gl, "???", GameVars.QUESTION_LOCATOIN, GameVars.TEXT_ALIGNMENT_CENTER);
		else
			Glyphs.drawString(gl, problemString, GameVars.QUESTION_LOCATOIN, GameVars.TEXT_ALIGNMENT_CENTER);
	}
	
	private void drawOverlay(GL10 gl, float alpha){
		gl.glPushMatrix();
		gl.glDisable(GL10.GL_TEXTURE_2D);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glFrontFace(GL10.GL_CW);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VertexBuffer.getVertexBuffer(overlay));

		gl.glColor4f(.0f, .0f, .0f, alpha);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, overlay.length / 3);

		gl.glColor4f(1, 1, 1, 1);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnable(GL10.GL_TEXTURE_2D);
		gl.glPopMatrix();
	}
	
	public boolean isLoaded(){ return isLoaded; }
	public boolean hasGraphicsLoaded(){ return hasGraphicsLoaded; }
	public boolean kill(){ return kill; }
	public boolean isPaused(){ return isPaused; }
	public boolean back(){ return backToSelection; }
	
	public void pause(){ isPaused = true; GameClock.getInstance().pause(); }
	public void resume(){ isPaused = false; GameClock.getInstance().resume(); }
	
	private void buttonHandler(int num){
		switch(num){
		// In case Retry does something different than Restart down the road.
		case GameVars.BUTTON_NUM_RETRY:
			reloading = true;
			break;
		case GameVars.BUTTON_NUM_RESUME:
			resume();
			break;
		case GameVars.BUTTON_NUM_RESTART:
			reloading = true;
			break;
		case GameVars.BUTTON_NUM_QUIT:
			kill = true;
			break;
		case GameVars.BUTTON_NUM_GOTO_MENU:
			kill = true;
			break;
		case GameVars.BUTTON_NUM_RETURN_TO_SELECTION:
			backToSelection = true;
			break;
		}
	}

	public void handleUp(PointF location) {
		if(isPaused){
			if(selectedButton != null){
				if(selectedButton.isPressed(location))
					buttonHandler(selectedButton.getNum());
				selectedButton = null;
				return;
			}
		}
		
		if(isWon){
			if(selectedButton != null){
				if(selectedButton.isPressed(location))
					buttonHandler(selectedButton.getNum());
				selectedButton = null;
				return;
			}
		}
		
		gui.handleUp(location);
	}

	public void handleDrag(PointF location) {
		gui.handleDrag(location);
	}

	public void handleTouch(PointF location) {
		if(isPaused){
			if(player.isDead()){
				if(retryButton.isPressed(location)) selectedButton = retryButton;
				if(quitButton.isPressed(location)) selectedButton = quitButton;
			}
			else for(pauseButtonIterator = 0; pauseButtonIterator < pauseButtonArray.length; ++pauseButtonIterator)
				if(pauseButtonArray[pauseButtonIterator].isPressed(location))
					selectedButton = pauseButtonArray[pauseButtonIterator];
			return;
		}
		
		if(isWon){
			if(returnToSelectionButton.isPressed(location)) selectedButton = returnToSelectionButton;
			if(victoryQuitButton.isPressed(location)) selectedButton = victoryQuitButton;
			if(victoryRetryButton.isPressed(location)) selectedButton = victoryRetryButton;
			
			return;
		}
		gui.handleTouch(location);
	}
	
	public boolean handleBackPress(){
		if(!isPaused)
			pause();
		else resume();
		return false;
	}
}